/*
* Copyright (c) 2007, Nubo Technologies
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
*    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*    * Neither the name of the Nubo Technologies nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package com.nubotech.gwt.oss.client;

import com.google.gwt.user.client.Command;
import com.nubotech.gwt.oss.client.auth.Credential;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 
 * Contains the service methods to online storage services like Amazon S3
 * @author jonnakkerud
 */
public abstract class OnlineStorageService {
    private Credential credential;

    /**
     * All the buckets for the account
     * @param cb The BucketResult callback that contains the list of Buckets
     */
    public abstract void listAllBuckets(BucketResultCallback cb);
    /**
     * Create a bucket
     * @param name The unique bucket name
     */
    public abstract void createBucket(String name);
    /**
     * Create a bucket with a canned access policy:
     *    AccessControlPolicy.PRIVATE Owner has full access, but no one else has access.
     *    AccessControlPolicy.PUBLIC_READ If this policy is used on an object, it can be read from a browser with no authentication.
     *    AccessControlPolicy.PUBLIC_READ_WRITE The anonymous principal is granted READ and WRITE access
     *    AccessControlPolicy.AUTHENTICATED_READ Any principal authenticated as a registered Amazon S3 user is granted READ access
     * @param name the unique bucket name
     * @param accessPolicy Access policy for the bucket
     */
    public abstract void createBucket(String name, int accessPolicy);    
    /**
     * Delete a bucket. Does not delete the objects in a bucket.
     * @param name the bucket name
     */
    public abstract void deleteBucket(String name);
    /**
     * List the objects contained in the named Bucket
     * @param bucketName the bucket name
     * @param cb The ObjectHolder callback 
     */
    public void listBucket(String bucketName, ObjectHolderResultCallback cb) {
        listBucket(bucketName, null, cb);
    }
    
    public abstract void listBucket(String bucketName, Map params, ObjectHolderResultCallback cb);

    public OnlineStorageService(Credential credential) {
        this.credential = credential;
    }
    
    /**
     * Put an object with data in a Bucket
     * @param bucketName the bucket name
     * @param key Unique key identifing the Object
     * @param data String data
     */
    public void putObject(String bucketName, String key, Object data) {
        ObjectHolder content = new ObjectHolder();
        content.setKey(key);
        content.setData(data);
        putObject(bucketName, content);        
    }
    
    /**
     * Put an object with data in a Bucket
     * @param bucketName The bucket name
     * @param content The ObjectHolder
     */
    public void putObject(String bucketName, ObjectHolder content) {
        Bucket b = new Bucket(bucketName);
        content.setBucket(b);
        putObject(content, null);
    }
    
    /**
     * Use an ObjectHolder to put an Object in a Bucket
     * @param content The ObjectHolder
     */
    public abstract void putObject(ObjectHolder content, RequestHeader[] headers);
    /**
     * An ObjectHolder will be returned in the specified callback
     * @param bucketName the bucket name
     * @param key the name for the object to get
     * @param cb The callback that will return the ObjectHolder
     */
    public void getObject(String bucketName, String key, ObjectHolderResultCallback cb) {
        getObject(bucketName, key, null, cb);
    }
    
    public abstract void getObject(String bucketName, String key, RequestHeader[] headers, ObjectHolderResultCallback cb);
    
    /**
     * Just the Object meta data will be placed in the ObjectHolder
     * @param bucketName the bucket name
     * @param key the key which identifies the object
     * @param cb the callback thet will return an ObjectHolderResult
     */
    public abstract void getObjectInfo(String bucketName, String key, ObjectHolderResultCallback cb);
    /**
     * Delete an Object in the specified Bucket
     * @param bucketName the bucket name
     * @param key the key
     */
    public abstract void deleteObject(String bucketName, String key);
    
    /**
     * Will create a link to the Object
     * @param bucketName the bucket name
     * @param key the key
     * @param expires time when the key expirs
     * @return the link
     */
    public abstract String createGetLink(String bucketName, String key, Date expires);
    
    // TODO logging 
    
    /**
     * return the access control policy for the bucket in a callback
     * @param bucketName the bucket name
     * @param cb the callback
     */
    public abstract void getAccessControlPolicy(String bucketName, AccessControlPolicyCallback cb);
    /**
     * get the access control policy for a object
     * @param bucketName the bucket name
     * @param key the object key
     * @param cb callback that will return an access policy
     */
    public abstract void getAccessControlPolicy(String bucketName, String key, AccessControlPolicyCallback cb);    
    /**
     * Update a buckets access control policy
     * @param bucketName the bucket name
     * @param policy the access control policy
     */
    public abstract void updateAccessControlPolicy(String bucketName, AccessControlPolicy policy);
    /**
     * updates the access control policy for an object
     * @param bucketName the bucket
     * @param key the object key
     * @param policy the access control policy
     */
    public abstract void updateAccessControlPolicy(String bucketName, String key, AccessControlPolicy policy);

    public Credential getCredential() {
        return credential;
    }

    public void setCredential(Credential credential) {
        this.credential = credential;
    }
    
    /**
     * Begins batch operations.  Service calls will be placed in a batch until commitBatch() is called.
     */
    public abstract void beginBatch();
    
    /**
     * Sends the batch service calls to the online storage service. A service will be called only after the previous service call has been successful
     */
    public abstract void commitBatch();
    
    /**
     * Sets the host name for the account, if it is differnt from the default. 
     * 
     * @param host The host name
     */
    public abstract void setHost(String host);
    
    /**
     * Return the host name.
     * 
     * @return The host name
     */
    public abstract String getHost();

}
